package com.zk.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.zk.util.WebServiceConstants;
import com.zk.util.XmlHandler;

/**
 * WebService服务响应对象
 * @author Anpengfei
 *
 */
public class Response implements Serializable{

	private static final long serialVersionUID = 1L;

	private Header header;	//	响应头
	
	private Result result;	//	响应结果
	
	private Object content;	//	响应内容
	
	private String xmlStr;	//	XML字符串格式的响应消息
	
	private Document xmlDoc;	//	XML文本格式的响应消息xmlStr
	
	/**
	 * 请求处理成功构造函数
	 * @param request	请求消息
	 * @param successDesc	成功消息描述
	 * @param object	消息内容
	 */
	@Deprecated
	public Response(Request request, String successDesc, Object... object) {
		this.header = request.getHeader();
		this.result = new Result(WebServiceConstants.MSG_RESULT_SUCCESS, successDesc);
		if(object != null && object.length > 0) {
			List<Object> list = new ArrayList<Object>();
			for(int i=0; i<object.length; i++) {
				list.add(object[i]);
			}
			this.content = list;
		}
		this.xmlStr = this.toXmlString();
		try {
			this.xmlDoc = DocumentHelper.parseText(this.xmlStr);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 请求处理成功构造函数
	 * @param header	请求消息头
	 * @param successDesc	成功消息描述
	 * @param object	消息内容
	 */
	public Response(Header header, String successDesc, Object... object) {
		this.header = header;
		this.result = new Result(WebServiceConstants.MSG_RESULT_SUCCESS, successDesc);
		if(object != null) {
			if(object.length <= 1) {
				this.content = object[0];
			} else {
				List<Object> list = new ArrayList<Object>();
				for(int i=0; i<object.length; i++) {
					list.add(object[i]);
				}
				this.content = list;
			}
		}
		this.xmlStr = this.toXmlString();
		try {
			this.xmlDoc = DocumentHelper.parseText(this.xmlStr);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 请求处理失败构造函数
	 * 失败原因描述规则：失败数据的主键+失败的理由
	 * @param request	请求消息
	 * @param failDesc	失败描述
	 */
	@Deprecated
	public Response(Request request, String failDesc) {
		this.header = request.getHeader();
		this.result = new Result(WebServiceConstants.MSG_RESULT_FAIL, failDesc);
		this.xmlStr = this.toXmlString();
		try {
			this.xmlDoc = DocumentHelper.parseText(this.xmlStr);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 请求处理失败构造函数
	 * 失败原因描述规则：失败数据的主键+失败的理由
	 * @param header	请求消息头
	 * @param failDesc	失败描述
	 */
	public Response(Header header, String failDesc) {
		this.header = header;
		this.result = new Result(WebServiceConstants.MSG_RESULT_FAIL, failDesc);
		this.xmlStr = this.toXmlString();
		try {
			this.xmlDoc = DocumentHelper.parseText(this.xmlStr);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取响应消息头
	 * @return	消息头
	 */
	public Header getHeader() {
		return this.header;
	}

	/**
	 * 获取接口处理结果
	 * @return	处理结果	
	 */
	public Result getResult() {
		return this.result;
	}

	/**
	 * 获取响应消息内容
	 * @return	响应消息内容
	 */
	public Object getContent() {
		return this.content;
	}
	
	/**
	 * 获取带UCD节点的XML字符串格式的响应消息
	 * @return	XML字符串格式的响应消息
	 */
	public String getXmlStr() {
		return this.xmlStr;
	}
	
	/**
	 * 获取XML文本格式的响应消息
	 * @return	XML文本格式的响应消息
	 */
	public Document getXmlDoc() {
		return this.xmlDoc;
	}
	
	/**
	 * response对象转换为xml字符串
	 * @return	xml字符串
	 */
	@SuppressWarnings("unchecked")
	private String toXmlString() {
		Element root = DocumentHelper.createElement(WebServiceConstants.MSG_RESPONSE_ROOT);
		root.add(XmlHandler.beanToXmlElement(this.header));	//	添加消息头
		root.add(XmlHandler.beanToXmlElement(this.result));	//	添加请求处理结果
		if(this.content == null) {
			return root.asXML();
		} else {
			if(this.content instanceof Map) {	//	消息内容为Map
				Map<String, String> map = (Map<String, String>) this.content;
				addMapContent(map, root);
			} else if(this.content instanceof List) {	//	消息内容为Map与JavaBean的混合对象
				List<Object> contents = (List<Object>) this.content;
				for(int i=0; i<contents.size(); i++) {
					Object object = contents.get(i);
					if(object instanceof Map) {
						addMapContent((Map<String, String>)object, root);
					} else {
						root.add(XmlHandler.beanToXmlElement(object, "serialVersionUID"));
					}
				}
			} else {	//	消息内容为JavaBean
				root.add(XmlHandler.beanToXmlElement(this.content, "serialVersionUID"));	//	添加回执内容
			}
			return root.asXML();
		}
	}

	/**
	 * 添加Map类的消息内容到响应消息的XML文本中
	 * @param map	键值对消息内容
	 * @param root	响应消息根节点元素
	 */
	private void addMapContent(Map<String, String> map, Element root) {
		Iterator<String> iterator = map.keySet().iterator();
		while(iterator.hasNext()) {
			String next = iterator.next();
			Element child = DocumentHelper.createElement(next);
			child.setText(map.get(next));
			root.add(child);
		}
	}
	
	public static void main(String[] args) {
		/*UserInfo userInfo = new UserInfo();
		userInfo.setEmail("1000000@qq.com");
		Header header = new Header("TCM_PLAT_06", WebServiceConstants.SYS_EMR_ID);
		System.out.print(new Response(header, "成功", userInfo).getXmlStr());*/
		try {
			Document doc = DocumentHelper.parseText("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><return>&lt;Response&gt;&lt;Header&gt;&lt;sender&gt;EMR&lt;/sender&gt;&lt;receiver&gt;HIS&lt;/receiver&gt;&lt;sendTime&gt;&lt;/sendTime&gt;&lt;msgType&gt;TCM_EMR_A05&lt;/msgType&gt;&lt;msgID&gt;&lt;/msgID&gt;&lt;/Header&gt;&lt;Result&gt;&lt;code&gt;1&lt;/code&gt;&lt;desc&gt;&#x6210;&#x529F;&lt;/desc&gt;&lt;/Result&gt;&lt;/Response&gt;</return></soap:Body></soap:Envelope>");
			doc.content();
			Element e = doc.getRootElement();
			Element re = e.element("return");
			System.out.print(re.getText());
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
}
